package com.zyq.support.ui;

import com.alibaba.fastjson.JSONObject;
import com.zyq.exportDir.Run;
import com.zyq.support.BaseController;
import com.zyq.support.BeanConfig;
import com.zyq.support.Context;
import com.zyq.support.ui.task.MoveOrCopyOrDelte;
import javafx.application.Platform;
import javafx.concurrent.Task;
import javafx.scene.Node;
import javafx.scene.control.Button;
import javafx.scene.control.CheckBox;
import javafx.scene.control.Label;
import javafx.scene.control.ProgressBar;
import javafx.scene.input.MouseEvent;
import javafx.stage.DirectoryChooser;
import javafx.stage.FileChooser;
import org.apache.commons.io.FileUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedHashSet;
import java.util.List;

public class MainController extends BaseController {
    private static final Logger logger = LoggerFactory.getLogger(MainController.class);
    public Button btn_move;
    public Button btn_copy;
    public Button btn_delete;
    public Label label_given_file;
    public CheckBox check_given_file;

    private BeanConfig config;

    private File src_dir;
    private File move_dir;
    private File copy_dir;

    public ProgressBar progress;
    public Label info;
    public CheckBox check_box_all_under_files;
    public Label label_choose_file;
    private File configFile;

    private List<Node> taskDisabled = new ArrayList<>();


    public MainController() {
        String configPath = Context.context.getBeanConfig();
        this.configFile = new File(configPath);
        if (configFile.exists()) {
            try {
                String configString = FileUtils.readFileToString(configFile, "utf-8");
                readConfig(configString);
            } catch (IOException e) {
                logger.error("读取配置文件失败", e);
            }
        } else {
            logger.info("配置文件不存在，进行创建");
            this.config = new BeanConfig();
            try {
                FileUtils.touch(configFile);
            } catch (IOException e) {
                logger.error("配置文件创建失败", e);
            }
        }
        Platform.runLater(this::showBack);
        initShouldDisabled();
    }

    private void readConfig(String config) {
        try {
            this.config = JSONObject.parseObject(config, BeanConfig.class);
        } catch (com.alibaba.fastjson.JSONException e) {
            this.config = new BeanConfig();
        }
    }

    private void writeConfig() {
        try {
            FileUtils.writeStringToFile(this.configFile, JSONObject.toJSONString(this.config), "utf-8");
        } catch (IOException e) {
            logger.error("写入配置失败", e);
        }
    }

    public void click_given_file(MouseEvent mouseEvent) {
        if (src_dir == null) {
            showInfo("提示", "请选择要操作的文件夹");
            clean_check_box_given_files();
            return;
        }
        if (check_given_file.isSelected()) {
            FileChooser fileChooser = new FileChooser();
            fileChooser.setTitle("请选择特定文件名文件（文件名用逗号隔开）");
            File file = fileChooser.showOpenDialog(Context.context.getStage());
            if (file != null) {
                check_box_given_files(file);
                writeConfig();
            } else {
                clean_check_box_given_files();
            }
        } else {
            clean_check_box_given_files();
        }
    }

    public void click_check_box_all_under_files(MouseEvent mouseEvent) {
        if (check_box_all_under_files.isSelected()) {
            DirectoryChooser fileChooser = new DirectoryChooser();
            fileChooser.setTitle("选择文件夹");
            File file = fileChooser.showDialog(Context.context.getStage());
            if (file != null) {
                check_box_all_under_files(file);
                this.config.setUnderFileDir(file.getAbsolutePath());
                writeConfig();
            } else {
                clean_check_box_all_under_files();
            }
        } else {
            clean_check_box_all_under_files();
        }
    }

    private void clean_check_box_given_files() {
        label_given_file.setText("");
        this.config.setGivenFile(null);
        check_given_file.setSelected(false);
        writeConfig();
    }

    private void clean_check_box_all_under_files() {
        src_dir = null;
        label_choose_file.setText("");
        this.config.setUnderFileDir(null);
        check_box_all_under_files.setSelected(false);
        writeConfig();
    }

    private void check_box_all_under_files(File file) {
        this.check_box_all_under_files.setSelected(true);
        this.src_dir = file;
        label_choose_file.setText("已选择" + this.src_dir.getAbsolutePath());
    }

    private void check_box_given_files(File file) {
        this.check_given_file.setSelected(true);
        this.config.setGivenFile(file.getAbsolutePath());
        label_given_file.setText("已选择" + file.getAbsolutePath());
    }

    private void showBack() {
        if (this.config.getUnderFileDir() != null) {
            check_box_all_under_files(new File(this.config.getUnderFileDir()));
        }
        if (this.config.getGivenFile() != null) {
            check_box_given_files(new File(this.config.getGivenFile()));
        }
    }

    public void click_move(MouseEvent mouseEvent) {
        if (move_dir == null) {
            DirectoryChooser directoryChooser = new DirectoryChooser();
            directoryChooser.setTitle("选择移动至文件夹");
            move_dir = directoryChooser.showDialog(Context.context.getStage());
        }
        if (src_dir != null && src_dir.isDirectory() && move_dir != null) {
            showConfirm("移动确认", String.format("确定移动%s至%s", src_dir.getAbsolutePath(), move_dir.getAbsolutePath()), () -> {
                File[] files = getOperaFiles();
                MoveOrCopyOrDelte moveTask = new MoveOrCopyOrDelte(files, move_dir, MoveOrCopyOrDelte.Type.move);
                moveTask.setCallBack(new MoveOrCopyOrDelte.CallBack() {
                    @Override
                    public void before() {
                        whenTasking();
                    }

                    @Override
                    public void after() {
                        tasked();
                    }
                });
                bindTask(info.textProperty(), moveTask.messageProperty());
                bindTask(progress.progressProperty(), moveTask.progressProperty());
                runTask(moveTask);
            }, () -> move_dir = null);
        }
    }

    private void whenTasking() {
        taskDisabled.forEach(n -> n.setDisable(true));
    }

    private void tasked() {
        taskDisabled.forEach(n -> n.setDisable(false));
    }

    private void initShouldDisabled() {
        Platform.runLater(() -> {
            taskDisabled.add(check_box_all_under_files);
            taskDisabled.add(btn_move);
            taskDisabled.add(btn_delete);
            taskDisabled.add(btn_copy);
        });
    }

    public void click_copy(MouseEvent mouseEvent) {
        if (copy_dir == null) {
            DirectoryChooser directoryChooser = new DirectoryChooser();
            directoryChooser.setTitle("选择复制至文件夹");
            copy_dir = directoryChooser.showDialog(Context.context.getStage());
        }
        if (src_dir != null && src_dir.isDirectory() && copy_dir != null) {
            showConfirm("复制确认", String.format("确定复制%s至%s", src_dir.getAbsolutePath(), copy_dir.getAbsolutePath()), () -> {
                File[] files = getOperaFiles();
                MoveOrCopyOrDelte copyTask = new MoveOrCopyOrDelte(files, copy_dir, MoveOrCopyOrDelte.Type.copy);
                copyTask.setCallBack(new MoveOrCopyOrDelte.CallBack() {
                    @Override
                    public void before() {
                        whenTasking();
                    }

                    @Override
                    public void after() {
                        tasked();
                    }
                });
                bindTask(info.textProperty(), copyTask.messageProperty());
                bindTask(progress.progressProperty(), copyTask.progressProperty());
                runTask(copyTask);
            }, () -> copy_dir = null);
        }

    }

    public void click_delete(MouseEvent mouseEvent) {
        if (src_dir == null) {
            showInfo("提示", "请选择要删除的文件");
            return;
        }
        showConfirm("确认删除", String.format("确认删除 %s吗?", src_dir.getAbsolutePath()), () -> {
            File[] files = getOperaFiles();
            MoveOrCopyOrDelte deleteTask = new MoveOrCopyOrDelte(files, null, MoveOrCopyOrDelte.Type.delete);
            deleteTask.setCallBack(new MoveOrCopyOrDelte.CallBack() {
                @Override
                public void before() {
                    whenTasking();
                }

                @Override
                public void after() {
                    tasked();
                    Platform.runLater(() -> {
                        clean_check_box_all_under_files();
                    });
                }
            });
            bindTask(info.textProperty(), deleteTask.messageProperty());
            bindTask(progress.progressProperty(), deleteTask.progressProperty());
            runTask(deleteTask);

        }, () -> {
        });
    }

    private File[] getOperaFiles() {
        File[] files;
        if (this.config.getGivenFile() != null) {
            File file = new File(this.config.getGivenFile());
            if (!file.exists()) {
                files = new File[0];
                showInfo("错误", String.format("%s 不存在", file.getAbsolutePath()));
            } else {
                try {
                    String file_names = FileUtils.readFileToString(file, "utf-8");
                    LinkedHashSet<String> names = new LinkedHashSet<>(Arrays.asList(file_names.split(",")));
                    List<File> file_list = new ArrayList<>();
                    names.forEach(s -> {
                        File children = new File(src_dir, s);
                        file_list.add(children);
                    });
                    files = file_list.toArray(new File[]{});
                } catch (IOException e) {
                    files = new File[0];
                    logger.error("读取文件名文件错误", e);
                }
            }
        } else {
            files = this.src_dir.listFiles();
        }
        return files;
    }

    public void createIDS(MouseEvent mouseEvent) {
        FileChooser chooser = new FileChooser();
        chooser.setTitle("选择数据库配置文件");
        File file = chooser.showOpenDialog(Context.getContext().getStage());
        if (file != null) {
            Task<Void> task = new Task<Void>() {
                @Override
                protected Void call() throws Exception {
                    try {
                        updateMessage("正在处理");
                        String path = "d:/ids";
                        Run.createIds(file, path);
                        updateMessage("处理完成，请前往" + path + "查看");
                    } catch (Exception e) {
                        logger.error("createIds:", e);
                        updateMessage("发生错误");
                    }
                    return null;
                }
            };
            bindTask(info.textProperty(), task.messageProperty());
            runTask(task);
        }
    }
}